package ldh.im.fxbase.util;

import org.apache.commons.dbutils.QueryRunner;
import org.slf4j.Logger;

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;

public class DbUtil {

    private static final Logger LOGGER = LoggerUtil.getFileLogger(DbUtil.class);

    public static <R> R transaction(SqlFunction<QueryRunner, Connection, R> function) throws SQLException {
        long st = System.currentTimeMillis();
        Connection connection = DbFactory.getInstance().getConnection();
        connection.setAutoCommit(false);
        R r = null;
        try {
            QueryRunner queryRunner = DbFactory.getInstance().buildQueryRunner();
            r = function.apply(queryRunner, connection);
            connection.commit();
            return r;
        } catch (Exception e) {
            LOGGER.error("sql error", e);
            connection.rollback();
            throw new SQLException(e);
        } finally {
            DbFactory.getInstance().close(connection);
            long time = System.currentTimeMillis() - st;
            if (time > 100) {
                LOGGER.info("transaction time {}", System.currentTimeMillis() - st);
            }
        }
    }

    public static <R> R query(SqlFunction<QueryRunner, Connection, R> function) throws SQLException {
        Connection connection = DbFactory.getInstance().getConnection();
        R r = null;
        try {
            QueryRunner queryRunner = DbFactory.getInstance().buildQueryRunner();
            r = function.apply(queryRunner, connection);
        } catch (Exception e) {
            LOGGER.error("sql error", e);
            throw new SQLException(e);
        }
        return r;
    }

    public static interface SqlFunction<QueryRunner, Connection, R> {
        R apply(QueryRunner queryRunner, Connection connection) throws SQLException, IOException;
    }
}
